;extern "C" void blit(Uint8 *image, Uint32 w, Uint32 h, Uint32 x, Uint32 y, Color rgb);

extern screen_pixeles
%define p_sprite [ebp + 8]		; El puntero al sprite.
%define wide [ebp + 12]			; El ancho del sprite.
%define height [ebp + 16]		; El alto del sprite.
%define x [ebp + 20]			; La coordena x de la pantalla donde empieza el sprite.
%define y [ebp + 24]			; La coordena y de la pantalla donde empieza el sprite.
%define color_off [ebp + 28]	; El color off.
%define i [ebp - 4]				; Variable local i.
%define j [ebp - 8]				; Variable local j.
%define SCREEN_W 800			; El ancho del screen.
%define SCREEN_H 400			; El alto del screen.

global blit

section .text

blit:
	push ebp
	mov ebp, esp
	sub esp, 8
	push edi
	push esi
	push ebx
	
	mov eax, height ; Muevo a eax el alto del sprite.
	mov dword i, eax ; Pongo en i el alto del sprite.
	
	mov eax, wide ; Muevo a eax el ancho del sprite.
	mov dword j, eax ; Pongo en j el ancho del sprite.
	
	; Me posicion en el screen en la posicion (x, y).
	mov edi, [screen_pixeles] ; Muevo a edi el puntero al screen.
	mov esi, SCREEN_W ; Muevo a esi el ancho del screen.
	lea ecx, [esi + esi * 2] ; Calculo en ecx la cantidad de bytes que tiene de ancho el screen.
	mov eax, y ; Muevo la coordenada y donde empieza el sprite a eax.
	mul ecx ; Multiplico la coordenada y por el ancho en bytes del screen.
	add edi, eax ; Sumo al puntero del screen el resultado anterior. Es decir me posiciono en y en el screen.
	mov ebx, x ; Muevo a ebx la coordenada x donde empieza el sprite.
	lea eax, [ebx + ebx * 2] ; Calculo en eax la cantidad de bytes que me tengo que correr para llegar a la pos x.
	add edi, eax ; Sumo a el puntero del screen el resultado anterior. Es decir me corro en x en el screen.
	
	mov esi, p_sprite ; Muevo a esi el puntero al sprite.
	
cicloFilasBlit:
	mov eax, wide ; Muevo a eax el ancho del sprite.
	mov dword j, eax ; Muevo a j el ancho del sprite que esta en eax.
	cmp dword i, 0 ; Comparo a i con 0.
	jne cicloColumnasBlit ; Si no es igual salto a cicloColumnasBlit.
	jmp fin ; Sino salto a fin.

cicloColumnasBlit:
	cmp dword j, 0 ; Comparo a j con 0.
	je finIteracionColumnasBlit ; Si es igual salto a finIteracionColumnasBlit.
	;Sino
	mov ebx, color_off ; Muevo a ebx el color_off.
	and ebx, 0x000000ff ; Obtengo el blue.
	cmp [esi], bl ; Comparo el pixel blue del sprite con el blue del color_off.
	je comparaGreenBlit	; Si es igual salto a comparaGreenBlit.
	jmp continuar ; Sino salto a continuar.

comparaGreenBlit:
	mov ebx, color_off ; Muevo a ebx el color_off.
	and ebx, 0x0000ff00 ; Obtengo el green.
	shr ebx,8 ; Para obtener el green en la parte baja hago un shift.
	cmp [esi+1], bl ; Comparo el pixel green del sprite con el green del color_off.
	je comparaRedBlit ; Si es igual salto a comparaRedBlit.
	jmp continuar ; Sino salto a continuar.

comparaRedBlit:
	mov ebx, color_off ; Muevo a ebx el color_off.
	and ebx, 0x00ff0000 ; Obtengo el red.
	shr ebx, 16 ; Para obtener el res en la parte baja hago un shift.
	cmp [esi+2], bl ; Comparo el pixel red del sprite con el red del color_off.
	jne continuar ; Si no es igual salto a continuar.
	;Sino quiere decir que es color_off. Entonces muevo el pixel byte a byte del screen al sprite.
	mov dl, [edi]
	mov [esi], dl
	mov dl, [edi+1]
	mov [esi+1], dl
	mov dl, [edi+2]
	mov [esi+2], dl
	
continuar:
	add dword esi,3 ; Sumo a esi 3. Es decir me corro un pixel(3 bytes) en el sprite.
	add dword edi,3 ; Sumo a edi 3. Es decir me corro un pixel (3 bytes) en el screen.
	sub dword j, 1 ; Le resto a j 1.
	jmp cicloColumnasBlit ; Salto a cicloColumnasBlit.
 
finIteracionColumnasBlit: 

;bajo de fila. Recalculo esi y edi
	mov edx, wide ; Muevo a edx el ancho en pixeles del sprite.
	mov ecx, edx ; Muevo a ecx el ancho en pixeles del sprite.
	and ecx, 0x3 ; Calculo la basura del sprite.
	add esi, ecx ; Sumo a el puntero del sprite la basura. Es decir salteo la basura.

	mov ebx, SCREEN_W ; Muevo a ebx el ancho en pixeles del screen.
	sub ebx, edx ; Le resto a el ancho en pixeles del screen el ancho pixeles del sprite.
	lea ebx, [ebx + ebx * 2] ; Calculo el  resultado anterior en bytes.
	add edi, ebx ; Le sumo al puntero del screen el resultado anterior es decir posiciono en la proxima fila.

	sub dword i, 1 ; Le resto a i 1.
	jmp cicloFilasBlit ; Salto a cicloFilasBlit.
	
fin:
	pop ebx
	pop esi
	pop edi
	add esp,8
	pop ebp
	ret
	